﻿namespace SKeeper.Application.Services.Invoice
{
    using Domain.Repositories;
    using Persistence.Repositories;
    using SKeeper.Persistence.Facade;
    using ViewModels.Invoice;
    using System.Linq;
    using System.Collections.Generic;
    using Domain.Invoices;
    using ViewModels.Warehouse;
    using System;
    using ViewModels.Items;
    public class InvoiceControllerService : IInvoiceControllerService
    {
        private IItemRepository itemRepository;
        private IInvoiceRepository invoiceRepository;
        private IStoredItemMovementRepository itemsMovementRepository;
        private IWarehouseRepository warehouseRepository;
        private IStoredItemRepository storedItemRepository;

        public InvoiceControllerService(DomainModelFacade context)
        {
            this.invoiceRepository = new InvoiceRepository(context);
            this.itemsMovementRepository = new StoredItemMovementRepository(context);
            this.warehouseRepository = new WarehouseRepository(context);
            this.itemRepository = new ItemRepository(context);
            this.storedItemRepository = new StoredItemRepository(context);
        }

        public InvoiceIndexViewModel GetIndexViewModel(string userId)
        {
            var warehouses = this.warehouseRepository.GetIncluding(x => x.Company).Where(x => x.Company.UserId == userId).ToList();

            return new InvoiceIndexViewModel
            {
                Warehouses = warehouses.Select(x => new WarehouseViewModel { Id = x.Id, Name = x.Name })
            };
        }

        public WarehouseInvoicesViewModel GetWarehouseInvoices(int id)
        {
            var warehouse = this.warehouseRepository.GetIncluding(x => x.Invoices).FirstOrDefault(x => x.Id == id);
            
            var invoices = warehouse.Invoices.ToList();

            if (invoices.Count == 0)
            {
                return new WarehouseInvoicesViewModel
                {
                    WarehouseId = id,
                    WarehouseName = warehouse.Name,
                    Invoices = new List<InvoiceViewModel>(),
                };
            }

            return new WarehouseInvoicesViewModel
            {
                WarehouseId = id,
                WarehouseName = warehouse.Name,
                Invoices = invoices.Select(x => new InvoiceViewModel { Id = x.Id, Code = x.Code, CreateDate = x.CreationDate })
            };
        }

        public InvoiceViewModel GetInvoiceViewModel(int invoiceId)
        {
            var invoice = this.invoiceRepository.GetIncluding(
                x => x.Warehouse,
                x => x.ItemsMovement,
                x => x.ItemsMovement.Select(y => y.StoredItem),
                x => x.ItemsMovement.Select(y => y.StoredItem.Item))
               .FirstOrDefault(x => x.Id == invoiceId);

            return InvoiceViewModel.FromInvoice(invoice);
        }

        public void CreateInvoice(InvoiceViewModel model)
        {
            Invoice invoice = model.ToInvoice();
            this.invoiceRepository.Create(invoice);
            var storedItems = new List<StoredItemMovement>();

            foreach(var itemMovementViewModel in model.Items)
            {
                var curentItemStored = this.storedItemRepository.GetAll().FirstOrDefault(x => x.ItemId == itemMovementViewModel.ItemId);
                if(curentItemStored == null)
                {
                    curentItemStored = new Domain.Warehouse.StoredItem
                    {
                        ItemId = itemMovementViewModel.ItemId,
                        LatestActivity = DateTime.Now,
                        Quantity = itemMovementViewModel.Quantity,
                        WarehouseId = model.WarehouseId
                    };

                            
                    
                    this.storedItemRepository.Create(curentItemStored);
                }

                StoredItemMovement item = itemMovementViewModel.ToStoredItemMovement();
                item.StoredItemId = curentItemStored.Id;
                item.StoredItem = curentItemStored;
                item.InvoiceId = invoice.Id;
                item.Price = itemMovementViewModel.Price;
                item.Quantity = itemMovementViewModel.Quantity;

                this.itemsMovementRepository.Create(item);
            }
        }

        public InvoiceViewModel InvoiceAddViewModel(int id)
        {
            var items = this.warehouseRepository
                .GetIncluding(x => x.Company, x => x.Company.Items)
                .First(x => x.Id == id)
                .Company
                .Items
                .ToList()
                .Select(x => ItemViewModel.FromItem(x))
                .ToList();

            var model = new InvoiceViewModel
            {
                WarehouseId = id,
                CreateDate = DateTime.Now,
                DueDate = DateTime.Now.AddDays(5),
                CompanyItems = items
            };

            return model;
        }
    }
}
